package com.example.service.impl;

import com.example.dao.CarDao;
import com.example.dao.OrderDao;
import com.example.dao.UserDao;
import com.example.entity.result.Result;
import com.example.entity.vo.Car;
import com.example.entity.vo.Order;
import com.example.entity.vo.State;
import com.example.exception.OperatorException;
import com.example.service.OrderService;
import com.example.utils.DataUtils;
import com.example.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderDao orderDao;
    @Autowired
    private CarDao carDao;
    @Autowired
    private UserDao userDao;

    //查询
    @Override
    public Result query(String key, String value) {
        DataUtils.paramCheckEmpty(key, value);
        switch (key) {
            case "all":
                return DataUtils.getResult(Result.SUCCESS, "orderAll", orderDao.selectAll());
            case "byId":
                return DataUtils.getResult(Result.SUCCESS, "order",
                        orderDao.selectById(DataUtils.paramToInteger(value)));
            case "byState":
                return DataUtils.getResult(Result.SUCCESS, "order",
                        orderDao.selectByState(value));
            case "byUser":
                return DataUtils.getResult(Result.SUCCESS, "order",
                        orderDao.selectByUser(DataUtils.paramToInteger(value)));
            case "byCar":
                return DataUtils.getResult(Result.SUCCESS, "order",
                        orderDao.selectByCar(DataUtils.paramToInteger(value)));
            case "byDate":
                HashMap<String, String> map = DataUtils.jsonToMap(value);
                DataUtils.paramCheckEmpty(key, value);
                return queryByDate(map);
            default:
                return DataUtils.getResult(Result.PARAMETER_INVALID);
        }
    }

    //添加
    @Override
    public Result insertOrder(Order order) {
        if (DataUtils.dataCompare(order, new Order(), Order.class) == 1.0) {
            return DataUtils.getResult(Result.PARAMETER_EMPTY);
        }
        if (order.getOid() != 0 && (orderDao.selectById(order.getOid()) != null)) {
            return DataUtils.getResult(Result.ERROR, "该订单已存在");
        }
        if (userDao.selectById(order.getUid()) == null) {
            return DataUtils.getResult(Result.ERROR, "该用户不存在");
        }
        if (carDao.selectById(order.getCid()) == null) {
            return DataUtils.getResult(Result.ERROR, "该汽车不存在");
        }
        order.setOState(State.NEW);
        Car car = carDao.selectById(order.getCid());
        Date transfer = DateUtils.Transfer(car.getAllowEnd());
        if (transfer.getTime()<new Date().getTime()){
            return DataUtils.getResult(Result.ERROR, "该车辆预约时间已过期");
        }
        check(order, car);
        List<Order> orders = orderDao.selectByCar(order.getCid());
        if (!orders.isEmpty()) {
            Date orderState = DateUtils.Transfer(order.getAppointmentStart());
            Date orderEnd = DateUtils.Transfer(order.getAppointmentStart());
            for (Order v : orders) {
                String oState = v.getOState();
                if (!oState.equals(State.CANCEL.getState()) && !oState.equals(State.COMPLETED.getState())) {
                    Date vState = DateUtils.Transfer(v.getAppointmentStart());
                    Date vEnd = DateUtils.Transfer(v.getAppointmentEnd());
                    if (vEnd.getTime() - orderState.getTime() > 0 || orderEnd.getTime() - vState.getTime() > 0) {
                        return DataUtils.getResult(Result.PARAMETER_INVALID, "该时间段已经有订单了");
                    }
                }
            }
        }
        String lastUpdate = DateUtils.getLastUpdate();
        order.setLastUpdate(lastUpdate);
        int add = orderDao.add(order);
        return (add > 0) ? DataUtils.getResult(Result.SUCCESS, "添加成功", orderDao.selectById(order.getOid())) :
                DataUtils.getResult(Result.ERROR, "添加失败");
    }

    //修改
    @Override
    public Result updateOrder(Order order) {
        if (DataUtils.dataCompare(order, new Order(), Order.class) == 1.0) {
            return DataUtils.getResult(Result.PARAMETER_EMPTY);
        }
        if (DataUtils.dataCompare(order, orderDao.selectById(order.getCid()), Order.class) == 1.0) {
            return DataUtils.getResult(Result.SUCCESS, "无更新");
        }
        Car car = carDao.selectById(order.getCid());
        check(order, car);
        int update = orderDao.update(order);
        return (update > 0) ? DataUtils.getResult(Result.SUCCESS, "修改成功") :
                DataUtils.getResult(Result.ERROR, "修改失败");
    }

    //删除
    @Override
    public Result delete(int oid) {
        if (orderDao.selectById(oid) == null) {
            return DataUtils.getResult(Result.ERROR, "找不到订单");
        }
        int delete = orderDao.delete(oid);
        return (delete > 0) ? DataUtils.getResult(Result.SUCCESS, "删除成功") :
                DataUtils.getResult(Result.ERROR, "删除失败");
    }

    //根据时间查询
    private Result queryByDate(HashMap<String, String> map) {
        if (map.get("start") == null || map.get("start") == null) {
            return DataUtils.getResult(Result.PARAMETER_MISSING, "缺少参数");
        }
        String start = map.get("start");
        String end = map.get("end");
        return DataUtils.getResult(Result.SUCCESS, "order", orderDao.selectByDate(start, end));
    }

    private void check(Order order, Car car) {
        long start = (DateUtils.Transfer(order.getAppointmentStart()).getTime())
                - (DateUtils.Transfer(car.getAllowStart()).getTime());
        long end = (DateUtils.Transfer(car.getAllowEnd()).getTime())
                - (DateUtils.Transfer(order.getAppointmentEnd()).getTime());
        if (start < 0 || end < 0) {
            throw new OperatorException("时间区间错误", Result.PARAMETER_INVALID);
        }
    }

    //设置状态
    public Result setOnState(Order order, State state) {
        int set = orderDao.setState(order.getOid(), state.getState());
        return (set > 0) ? DataUtils.getResult(Result.SUCCESS, "更新成功") :
                DataUtils.getResult(Result.ERROR, "更新失败");
    }

    public List<Order> queryAll() {
        return orderDao.selectAll();
    }

}
